// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ValueExpiry.cs" company="XamlNinja">
//   2011 Richard Griffin and Ollie Riches
// </copyright>
// <summary>
// </summary>
// <credits>
// Pete Blois http://blois.us/blog/2009/04/datatrigger-bindings-on-non.html
// </credits>
// <credits>
// StuartHarris http://red-badger.com/Blog/post/Watching-Silverlight-Dependency-Properties-with-Reactive-Extensions.aspx#comment
// </credits>
// --------------------------------------------------------------------------------------------------------------------

namespace WP7Contrib.View.Controls.BindingListener
{
    using System;
    using System.Windows;
    using System.Windows.Data;

    public class DependencyPropertyListener
    {
        private readonly DependencyProperty dependencyProperty;

        private FrameworkElement targetElement;

        public DependencyPropertyListener()
        {
            this.dependencyProperty = DependencyProperty.RegisterAttached(
                Guid.NewGuid().ToString(), 
                typeof(object), 
                typeof(DependencyPropertyListener), 
                new PropertyMetadata(null, this.OnValueChanged));
        }

        public event EventHandler<ValueChangedEventArgs> ValueChanged;

        public event EventHandler<BindingChangedEventArgs> Changed;

        void HandleValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            OnChanged(new BindingChangedEventArgs(e));
        }

        protected void OnChanged(BindingChangedEventArgs e)
        {
            var temp = Changed;
            if (temp != null)
            {
                temp(targetElement, e);
            }
        }

        public void Attach(FrameworkElement target, Binding binding)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            if (binding == null)
            {
                throw new ArgumentNullException("binding");
            }

            this.Detach();
            this.targetElement = target;
            this.targetElement.SetBinding(this.dependencyProperty, binding);
        }

        public void Detach()
        {
            if (this.targetElement != null)
            {
                this.targetElement.ClearValue(this.dependencyProperty);
                this.targetElement = null;
            }
        }

        private void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            EventHandler<ValueChangedEventArgs> handler = this.ValueChanged;
            if (handler != null)
            {
                handler(this, new ValueChangedEventArgs(e.OldValue, e.NewValue));
            }
        }
    }
}